package bank;


import java.util.ArrayList;

/**
   This bank contains a collection of bank accounts.
*/
public class Bank
{   
   
	// Attributes
	private ArrayList<BankAccount> accounts;
	
	/**
      Constructs a bank with no bank accounts.
   */
   public Bank()
   {
      accounts = new ArrayList<BankAccount>();
   }

   /**
      Adds an account to this bank.
      @param acctNum account number of the new account
      @param initialDeposit initial funds of the new account
   */
   public void addAccount(int acctNum, double initialDeposit)
   {
	 BankAccount newAccount = new BankAccount(acctNum, initialDeposit);
	 this.accounts.add(newAccount);
   }
   
   /**
   Adds an account to this bank.
   @param a the account to add
   */
   public void addAccount(BankAccount a)
   {
      accounts.add(a);
   }
   
   /**
      Gets the sum of the balances of all accounts in this bank.
      @return the sum of the balances
   */
   public double getTotalBalance()
   {
      double total = 0;
      for (BankAccount a : accounts)
      {
         total = total + a.getBalance();
      }
      return total;
   }

   /**
      Counts the number of bank accounts whose balance is at
      least a given value.
      @param atLeast the balance required to count an account
      @return the number of accounts having least the given balance
   */
   public int count(double atLeast)
   {
      int matches = 0;
      for (BankAccount a : accounts)
      {
         if (a.getBalance() >= atLeast) matches++; // Found a match
      }
      return matches;
   }

   /**
      Finds a bank account with a given number.
      @param accountNumber the number to find
      @return the account with the given number, or null if there
      is no such account
   */
   public BankAccount find(int accountNumber)
   {
      for (BankAccount a : accounts)
      {
         if (a.getAccountNumber() == accountNumber) // Found a match
            return a;
      } 
      return null; // No match in the entire array list
   }

   /**
      Gets the bank account with the largest balance.
      @return the account with the largest balance, or null if the
      bank has no accounts
   */
   public BankAccount getMaximum()
   {
      if (accounts.size() == 0) return null;
      BankAccount largestYet = accounts.get(0);
      for (int i = 1; i < accounts.size(); i++) 
      {
         BankAccount a = accounts.get(i);
         if (a.getBalance() > largestYet.getBalance())
            largestYet = a;
      }
      return largestYet;
   }
   
   /**
   makes a deposit
   @param acctNum the account number
   @param amount the amount of the transaction
    */
   public void deposit(int acctNum, double amount)
   {
	   this.find(acctNum).deposit(amount);
   }
   
   /**
   makes a withdrawal
   @param acctNum the account number
   @param amount the amount you wish to withdraw
    */
   public void withdraw(int acctNum, double amount)
   {
	   this.find(acctNum).withdraw(amount);
   }
   
   /**
   Gets you the balance of the account
   @param acctNum the account number
   @return the balance
    */
   public double getBalance(int acctNum)
   {
	   return this.find(acctNum).getBalance();
   }
   
   /**
   Suspends the requested account (unless it is closed)
   @param acctNum the account number
   */
   public void suspendAccount(int acctNum)
   {
	   this.find(acctNum).suspend();
   }
   
   /**
   Opens the requested account (unless it is closed)
   @param acctNum the account number
   */
   public void openAccount(int acctNum)
   {
	   this.find(acctNum).open();
   }
   
   /**
   Closes the requested account after withdrawing all
   available funds
   @param acctNum the account number
   */
   public void closeAccount(int acctNum)
   {
	   this.find(acctNum).withdraw(this.find(acctNum).getBalance());
	   this.find(acctNum).close();
   }
   
   /**
   Gets the status of the account
  @param acctNum the account number
  @return the status of the account
   */
   public String getAccountStatus(int acctNum)
   {
	   return this.find(acctNum).getStatus();
   }
   
   /**
   Gets all transactions for the requested account
   @param acctNum the account number
   @return a string of the transactions of this account
    */
   public String accountTransactionsString(int acctNum)
   {
	   return this.find(acctNum).transactionsString();
   }
   
   /**
   Summarizes all of the accounts
   @return a String - the summary of all the accounts
    */
   public String summarizeAllAccounts()
   {
	   String outputString = "Bank Account Summary\n\nAccount        Balance      #Transactions      Status\n";
	   for (BankAccount account : accounts)
	   {
		   outputString = outputString + account.getAccountNumber() + "            ";
		   outputString = outputString + account.getBalance() + "         ";
		   outputString = outputString + account.numTransactions() + "              ";
		   outputString = outputString + account.getStatus() + "\n";
	   }
	   outputString = outputString + "End of Account Summary";
	   return outputString;
   }
}